﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace Weazel.Willows.PreliminaryModel
{
	public class Channel :
		TypedItem
	{
		private ChannelType channelType;
		public ChannelType ChannelType
		{
			get { return channelType; }
		}

		private int length;
		public int Length
		{
			get { return length; }
		}

		public Channel(			
			Model model, 
			IdentifierMap identifierMap,
			List<ModelError> errors,
			XmlElement description
		)
			: base(model)
		{
			read(identifierMap, errors, description);
		}

		#region Read from XML
		private void read(IdentifierMap identifierMap, List<ModelError> errors, XmlElement description)
		{
			System.Diagnostics.Trace.Assert(description.HasAttribute("name"));

			if (description.Name == "Queue")
			{
				System.Diagnostics.Trace.Assert(description.HasAttribute("length"));
				channelType = ChannelType.Queue;
				length = int.Parse(description.Attributes["length"].Value);
			}
			else if (description.Name == "Signal")
				channelType = ChannelType.Signal;
			else
				// unexpected
				throw new NotSupportedException();

			this.Name = description.Attributes["name"].Value;
			ReadType(description);

			identifierMap.Add(Name, this);
		}
		#endregion

		public void ExpandTo(Weazel.Willows.Model.Module module, HierarchicalName hierarchicalName)
		{
			string uniqueName = hierarchicalName.CreateUniqueName(Name);

			switch (channelType)
			{
				case ChannelType.Signal:
					{
						Weazel.Willows.Model.Signal signal =
							new Weazel.Willows.Model.Signal(
								module,
								Model.TypeRegistry,
								Type,
								Name,
								uniqueName
							);

						module.Channels.Add(Name, signal);
						break;
					}
				case ChannelType.Queue:
					{
						Weazel.Willows.Model.Queue queue =
							new Weazel.Willows.Model.Queue(
								module,
								Model.TypeRegistry,
								Type,
								Name,
								uniqueName,
								length
							);

						module.Channels.Add(Name, queue);
						break;
					}

				default:
					throw new NotSupportedException();
			}
		}
	}
}
